#include "StdAfx.h"
#include "DxVertexBuffer.h"
#include "DxRenderer.h"
#include "DxVertexFormat.h"

DxVertexBuffer::DxVertexBuffer(void)
{
	m_pVertexBuffer = 0;
	m_pFormat = 0;
	m_bLocked = false;
	m_iSize = 0;
	m_iVertCount = 0;
	m_pLockPointer = 0;
}


DxVertexBuffer::~DxVertexBuffer(void)
{
	if( m_pVertexBuffer )
		m_pVertexBuffer->Release();

	if( m_pFormat )
		delete m_pFormat;

}

/**
 * Creates a new vertex buffer the the capcity for the specified amount of vertices.
 * BRF 05/08/11
 **/
bool DxVertexBuffer::CreateBuffer(int iCount)
{
	m_pFormat = new DxVertexFormat();
	int iSize = m_pFormat->GetSize() * iCount;
	if( FAILED(DxRenderer::GetInstance()->GetDevice()->CreateVertexBuffer(iSize, 0, 0, D3DPOOL_MANAGED, &m_pVertexBuffer, NULL)) )
	{
		delete m_pFormat;
		m_pFormat = 0;
		return false;
	}

	m_iSize= iSize;
	m_iVertCount = iCount;

	return true;
}

/**
 * Locks the vertex buffer so it can be accessed
 * BRF 05/08/11
 **/
bool DxVertexBuffer::Lock()
{
	if( !m_bLocked )
	{
		if( m_pVertexBuffer->Lock(0, 0, (void**)&m_pLockPointer, 0) == D3D_OK)		
			m_bLocked = true;
	}

	return m_bLocked;
}

/**
 * Unlocks the vertex buffer so it can be drawn
 * BRF 05/08/11
 **/
bool DxVertexBuffer::UnLock()
{
	if( m_bLocked )
	{
		if( m_pVertexBuffer->Unlock() == D3D_OK )
		{
			m_bLocked = false;		
			m_pLockPointer = 0;
		}
	}

	return !m_bLocked;
}

/**
 * This section is used to set the components of a vertex
 *
 * BRF 05/10/11
 **/

void DxVertexBuffer::SetPosition(int iVertex, Vector4 &vPos)
{
	if( m_bLocked )
	{
		Vector4* v = (Vector4*)&m_pLockPointer[iVertex * m_pFormat->GetSize() + m_pFormat->GetOffset(DxVertexFormat::eVC_Position)];
		v->Set(vPos.GetX(), vPos.GetY(), vPos.GetZ(), 1.0f);
	}

}

void DxVertexBuffer::SetNormal(int iVertex, Vector4 &vNorm)
{
	if( m_bLocked )
	{
		Vector4* v = (Vector4*)&m_pLockPointer[iVertex * m_pFormat->GetSize() + m_pFormat->GetOffset(DxVertexFormat::eVC_Normal)];
		v->Set(vNorm.GetX(), vNorm.GetY(), vNorm.GetZ(), 1.0f);
	}

}

void DxVertexBuffer::SetTexCoord(int iVertex, Vector4 &vTexCoord)
{
	if( m_bLocked )
	{
		Vector4* v = (Vector4*)&m_pLockPointer[iVertex * m_pFormat->GetSize() + m_pFormat->GetOffset(DxVertexFormat::eVC_TexCoord)];
		v->Set(vTexCoord.GetX(), vTexCoord.GetY(), 0.0f, 1.0f);
	}

}

void DxVertexBuffer::SetBlendWeights(int iVertex, Vector4 &vBlendWeights)
{
	if( m_bLocked )
	{
		Vector4* v = (Vector4*)&m_pLockPointer[iVertex * m_pFormat->GetSize() + m_pFormat->GetOffset(DxVertexFormat::eVC_BlendWeights)];
		v->Set(vBlendWeights.GetX(), vBlendWeights.GetY(), vBlendWeights.GetZ(), vBlendWeights.GetW());
	}
}

void DxVertexBuffer::SetBlendIndices(int iVertex, u32 uIndices)
{
	if( m_bLocked )
	{
		u32* u = (u32*)&m_pLockPointer[iVertex * m_pFormat->GetSize() + m_pFormat->GetOffset(DxVertexFormat::eVC_BlendWeights)];		
		(*u) = uIndices;
	}
}

//End of setting vertex components